// 在柠檬水摊上，每一杯柠檬水的售价为 5 美元。
// 顾客排队购买你的产品，（按账单 bills 支付的顺序）一次购买一杯。
// 每位顾客只买一杯柠檬水，然后向你付 5 美元、10 美元或 20 美元。
// 你必须给每个顾客正确找零，也就是说净交易是每位顾客向你支付 5 美元。
// 注意，一开始你手头没有任何零钱。

// 如果你能给每位顾客正确找零，返回 true ，否则返回 false 。

const lemonadeChange = function (bills: number[]): boolean {
    // 初始化三种纸币
    let five: number = 0;
    let ten: number = 0;
    let twenty: number = 0;
    for (let i = 0; i < bills.length; i++) {
        let currLess: number = bills[i] - 5; // 应找零
        // 找零过程，先找大钱再找小钱
        while (currLess > 0) {
            if (currLess >= 20 && twenty > 0) {
                currLess -= 20;
                twenty--;
            } else if (currLess >= 10 && ten > 0) {
                currLess -= 10;
                ten--;
            } else if (currLess >= 5 && five > 0) {
                currLess -= 5;
                five--;
            } else {
                return false;
            }
        }
        // 收钱过程
        if (bills[i] === 5) {
            five++;
        } else if (bills[i] === 10) {
            ten++;
        } else if (bills[i] === 20) {
            twenty++;
        }
    }
    return true;
};


// 这道题目其实蛮意外，没有什么特别的巧妙解法
// 基本上就是直接模拟现实中找钱的过程而已
// 这里唯一值得注意的地方是应该先找大钱再找小钱
// 因为小钱的灵活性更强，某种程度上来讲也更珍贵，所以if判断的时候大币种纸币应该提前。